// Copyright (c) MatrixFramework. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System.ComponentModel.DataAnnotations;

namespace MatrixFramework.Keycloak.Abstractions.Options;

/// <summary>
/// Keycloak配置选项
/// </summary>
public class KeycloakOptions
{
    /// <summary>
    /// 配置节名称
    /// </summary>
    public const string SectionName = "MatrixFramework:Keycloak";

    /// <summary>
    /// Keycloak服务地址
    /// </summary>
    [Required(ErrorMessage = "Keycloak BaseUrl 是必需的")]
    [Url(ErrorMessage = "BaseUrl 必须是有效的URL")]
    public string BaseUrl { get; set; } = string.Empty;

    /// <summary>
    /// 管理员客户端ID
    /// </summary>
    [Required(ErrorMessage = "AdminClientId 是必需的")]
    public string AdminClientId { get; set; } = "admin-cli";

    /// <summary>
    /// 管理员客户端密钥
    /// </summary>
    [Required(ErrorMessage = "AdminClientSecret 是必需的")]
    public string AdminClientSecret { get; set; } = string.Empty;

    /// <summary>
    /// 默认Realm
    /// </summary>
    [Required(ErrorMessage = "DefaultRealm 是必需的")]
    public string DefaultRealm { get; set; } = "MatrixFramework";

    /// <summary>
    /// 管理员用户名
    /// </summary>
    [Required(ErrorMessage = "AdminUsername 是必需的")]
    public string AdminUsername { get; set; } = string.Empty;

    /// <summary>
    /// 管理员密码
    /// </summary>
    [Required(ErrorMessage = "AdminPassword 是必需的")]
    public string AdminPassword { get; set; } = string.Empty;

    /// <summary>
    /// 连接超时时间（秒）
    /// </summary>
    [Range(1, 300, ErrorMessage = "TimeoutSeconds 必须在1-300秒之间")]
    public int TimeoutSeconds { get; set; } = 30;

    /// <summary>
    /// 重试次数
    /// </summary>
    [Range(0, 10, ErrorMessage = "RetryCount 必须在0-10次之间")]
    public int RetryCount { get; set; } = 3;

    /// <summary>
    /// 重试间隔（毫秒）
    /// </summary>
    [Range(100, 60000, ErrorMessage = "RetryDelayMs 必须在100-60000毫秒之间")]
    public int RetryDelayMs { get; set; } = 1000;

    /// <summary>
    /// 是否启用日志记录
    /// </summary>
    public bool EnableLogging { get; set; } = true;

    /// <summary>
    /// 是否启用请求跟踪
    /// </summary>
    public bool EnableTracing { get; set; } = false;

    /// <summary>
    /// JWT Token过期缓冲时间（分钟）
    /// </summary>
    [Range(1, 60, ErrorMessage = "TokenExpirationBufferMinutes 必须在1-60分钟之间")]
    public int TokenExpirationBufferMinutes { get; set; } = 5;

    /// <summary>
    /// HTTP客户端配置
    /// </summary>
    public HttpClientOptions HttpClient { get; set; } = new();

    /// <summary>
    /// 多租户配置
    /// </summary>
    public MultiTenantOptions MultiTenant { get; set; } = new();
}

/// <summary>
/// HTTP客户端配置选项
/// </summary>
public class HttpClientOptions
{
    /// <summary>
    /// 自定义User-Agent
    /// </summary>
    public string UserAgent { get; set; } = "MatrixFramework.Keycloak/1.0";

    /// <summary>
    /// 是否启用自动重试
    /// </summary>
    public bool EnableAutoRetry { get; set; } = true;

    /// <summary>
    /// 熔断器配置
    /// </summary>
    public CircuitBreakerOptions CircuitBreaker { get; set; } = new();
}

/// <summary>
/// 熔断器配置选项
/// </summary>
public class CircuitBreakerOptions
{
    /// <summary>
    /// 是否启用熔断器
    /// </summary>
    public bool Enabled { get; set; } = true;

    /// <summary>
    /// 失败阈值
    /// </summary>
    [Range(1, 100, ErrorMessage = "FailureThreshold 必须在1-100之间")]
    public int FailureThreshold { get; set; } = 5;

    /// <summary>
    /// 断路持续时间（秒）
    /// </summary>
    [Range(5, 300, ErrorMessage = "DurationOfBreakSeconds 必须在5-300秒之间")]
    public int DurationOfBreakSeconds { get; set; } = 30;

    /// <summary>
    /// 半开状态的采样数量
    /// </summary>
    [Range(1, 100, ErrorMessage = "SamplingDurationMilliseconds 必须在1-100之间")]
    public int SamplingDurationMilliseconds { get; set; } = 10000;
}

/// <summary>
/// 多租户配置选项
/// </summary>
public class MultiTenantOptions
{
    /// <summary>
    /// 是否启用多租户支持
    /// </summary>
    public bool Enabled { get; set; } = true;

    /// <summary>
    /// 租户隔离策略
    /// </summary>
    public TenantIsolationStrategy IsolationStrategy { get; set; } = TenantIsolationStrategy.Realm;

    /// <summary>
    /// 租户标识符前缀
    /// </summary>
    public string TenantPrefix { get; set; } = "tenant-";

    /// <summary>
    /// 默认Realm模板
    /// </summary>
    public string DefaultRealmTemplate { get; set; } = "{tenant-id}";

    /// <summary>
    /// 是否为每个租户创建独立的Realm
    /// </summary>
    public bool CreateRealmsPerTenant { get; set; } = true;

    /// <summary>
    /// Realm命名策略
    /// </summary>
    public RealmNamingStrategy RealmNaming { get; set; } = RealmNamingStrategy.TenantId;
}

/// <summary>
/// 租户隔离策略
/// </summary>
public enum TenantIsolationStrategy
{
    /// <summary>
    /// 无隔离
    /// </summary>
    None = 0,

    /// <summary>
    /// 基于Realm隔离
    /// </summary>
    Realm = 1,

    /// <summary>
    /// 基于客户端隔离
    /// </summary>
    Client = 2,

    /// <summary>
    /// 基于角色隔离
    /// </summary>
    Role = 3
}

/// <summary>
/// Realm命名策略
/// </summary>
public enum RealmNamingStrategy
{
    /// <summary>
    /// 使用租户ID
    /// </summary>
    TenantId = 0,

    /// <summary>
    /// 使用租户名称
    /// </summary>
    TenantName = 1,

    /// <summary>
    /// 使用租户代码
    /// </summary>
    TenantCode = 2,

    /// <summary>
    /// 使用自定义前缀+租户ID
    /// </summary>
    CustomPrefix = 3
}